package cz.none.bezbarier.web.security;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import cz.none.bezbarier.web.model.Role;
import cz.none.bezbarier.web.repository.UserRepository;

@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {

	private static final Logger LOG = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

	@Autowired
	private UserRepository repository;

	@Override
	public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
		LOG.debug("loadUserByUsername :: start");
		cz.none.bezbarier.web.model.User user = repository.findUserByEmail(email);
		if (null == user) {
			LOG.info("User not found");
			throw new UsernameNotFoundException("User not found");
		}

		UserDetails details = new User(user.getEmail(), user.getPassword(), user.isActive(), true, true,
				!user.isLocked(), getAuthories(user));
		LOG.debug("loadUserByUsername :: end");
		return details;
	}

	private List<GrantedAuthority> getAuthories(cz.none.bezbarier.web.model.User user) {
		if (null == user) {
			return null;
		}
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		Role role = user.getRole();
		while (true) {
			authorities.add(new SimpleGrantedAuthority(role.name()));

			role = role.getSubordination();
			if (null == role) {
				break;
			}
		}

		return authorities;
	}

}
